package club.kynb.mall.application.flow.user;

import club.kynb.mall.application.config.AuthConfig;
import club.kynb.mall.application.config.AuthProperties;
import club.kynb.mall.application.context.AuthenticationContext;
import club.kynb.mall.application.limiter.AuthFailedCountLimiter;
import club.kynb.mall.application.constant.MallResultCode;
import club.kynb.mall.application.model.model.command.AuthenticationCommand;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.pizza.common.web.exception.Errors;
import org.pizza.pattern.filter.Filter;
import org.pizza.pattern.filter.FilterInvoker;
import org.springframework.stereotype.Component;

import java.util.Optional;

/**
 * @author kynb_club@163.com
 * @since 2020/12/18 1:48 下午
 * 检查是否超出登录失败限制过滤器
 */
@Slf4j
@AllArgsConstructor
@Component
public class CheckAuthFailedCountFilter implements Filter<AuthenticationContext> {
    private final AuthFailedCountLimiter authFailedCountLimiter;
    private final AuthProperties authProperties;
    @Override
    public void doFilter(AuthenticationContext authenticationContext, FilterInvoker<AuthenticationContext> filterInvoker) {
        log.info("检查是否超出登录失败限制过滤器 start");
        AuthenticationCommand authenticationCommand = authenticationContext.getAuthenticationCommand();
        Optional<AuthConfig> authConfig = authProperties.get(authenticationCommand.getClientType());
        AuthConfig config = authConfig.orElseThrow(() -> Errors.BIZ.exception("丢失对应客户端类型的认证配置"));
        boolean exceedCount = authFailedCountLimiter.isExceedCount(authenticationCommand.getPhone(), config.getFailedCount());
        if (exceedCount) {
            long lockTime = authFailedCountLimiter.lockTime(authenticationCommand.getPhone());
            if (lockTime > 0) {
                lockTime = lockTime / 60;
            }
            throw Errors.BIZ.exception(String.format(MallResultCode.CODE_11001.msg(), config.getFailedCount(), lockTime + 1));
        }
        log.info("检查是否超出登录失败限制过滤器 end");
        filterInvoker.invoke(authenticationContext);
    }
}
